/**
 * 
 */
package fr.univ_tln.inf9.exaplanning.api.composante;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import javax.swing.event.EventListenerList;

import fr.univ_tln.inf9.exaplanning.api.administration.Administrator;
import fr.univ_tln.inf9.exaplanning.api.composante.event.AdminChangedEvent;
import fr.univ_tln.inf9.exaplanning.api.composante.event.AdminListener;
import fr.univ_tln.inf9.exaplanning.api.composante.event.ListTraining_pathListener;
import fr.univ_tln.inf9.exaplanning.api.composante.event.Training_pathAddedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.composante.event.Training_pathRemovedToListEvent;
import fr.univ_tln.inf9.exaplanning.api.db.AbstractEntity;
import fr.univ_tln.inf9.exaplanning.api.db.EntityInfo;
import fr.univ_tln.inf9.exaplanning.api.db.SessionManager;



/**
 * @author emilien
 * @author ventura (controller)
 * 
 */
@EntityInfo(	collections = { TrainingPath.class },
				key = "name",
				methods = { "getName", "getAdmin" },
				rows = { "name_component", "email" },
				table = "component",
				variables = { "admin" }) 
public class Component extends AbstractEntity {
	
	private final String name;
	private String admin;
	private List<String> training_paths;
	private EventListenerList listeners;
	
	public Component(String name, Administrator admin) throws IOException, SQLException {
		super(true);
		this.name = name;
		this.admin = (admin.getEmail());
	}
	
	private Component(String name, String admin) throws IOException, SQLException {
		super(false);
		this.name = name;
		this.admin = admin;
	}

	public String getName() {
		return name;
	}

	public List<String> getTraining_paths() {
		return training_paths;
	}
	
	
	/**
	 * Ce fire permet de signaler q'un training a été ajouté
	 * @param trainingPath
	 */
	public void addTraining_path(TrainingPath trainingPath) {
		training_paths.add(trainingPath.getName());
		fireAddTraining_pathToList(trainingPath.getName());
	}
	
	public void removeTraining_path(String training_path) {
		training_paths.remove(training_path);
		fireRemoveTraining_pathToList(training_path);
	}
	
	/****************************************************************************************************************/
	/****************************************			LISTENER				*************************************/
	 /*********************Cette partie est utile pour l'implentation du modèle MVC 			*********************/
	/****************************************************************************************************************/
	
	
	/**
	 * Gestion des listeners sur training path
	 */
	
	public void addListTraining_pathListener(ListTraining_pathListener listener){
		listeners.add(ListTraining_pathListener.class, listener);
	}
	
	public void removeListTraining_pathListener(ListTraining_pathListener l){
		 listeners.remove(ListTraining_pathListener.class, l);
	}
	
	
	/**
	 * Définition de fire sur training_path
	 * @param elementAdded
	 */
	private void fireAddTraining_pathToList(String elementAdded) {
		ListTraining_pathListener[] listenerList = (ListTraining_pathListener[])listeners.getListeners(ListTraining_pathListener.class);
		
		for(ListTraining_pathListener listener : listenerList){
			listener.Training_pathAddedToList(new Training_pathAddedToListEvent(this, elementAdded));
		}
		
	}
	
	
private void fireRemoveTraining_pathToList(String elementRemoved) {
		ListTraining_pathListener[] listenerList = (ListTraining_pathListener[])listeners.getListeners(ListTraining_pathListener.class);
		
		for(ListTraining_pathListener listener : listenerList){
			listener.Training_pathRemovedToList(new Training_pathRemovedToListEvent(this, elementRemoved));
		}
		
	}

	public void setAdmin(Administrator admin) {
		this.admin = admin.getEmail();
		fireObjectChanged();
		fireAdminChanged();
	}

	public void addAdminListener(AdminListener listener){
		listeners.add(AdminListener.class, listener);
	}
	
	public void removeAdminListener(AdminListener l){
		 listeners.remove(AdminListener.class, l);
	}
	
	private void fireAdminChanged() {
		AdminListener[] listenerList = (AdminListener[])listeners.getListeners(AdminListener.class);
		
		for(AdminListener listener : listenerList){
			listener.AdminChanged(new AdminChangedEvent(this, getAdmin()));
		}
		
	}
	
	public String getAdmin() {
		return admin;
	}
	
	public static Component findByKey(String key) throws IOException, SQLException {
    	List<List<String>> data = SessionManager.getInstance().getData(Component.class, key);
    	
    	List<String> variables = data.get(0);
    	Component result = new Component(variables.get(0), variables.get(1));
    	result.training_paths = data.get(1);
    	
    	return result;
	}
}
